<?php

namespace app\admin\service;


use app\admin\model\DeviceBind;
use app\admin\model\DeviceImei;
use app\admin\model\DeviceUnbind;
use app\admin\model\Student;
use app\admin\model\User;
use think\Db;

/**
 * 设备绑定管理-服务类
 * Class DeviceBindService
 * @package app\admin\service
 */
class DeviceBindService extends BaseService
{
    /**
     * 构造函数
     */
    public function __construct()
    {
        $this->model = new DeviceBind();
    }

    public function stuedit()
    {
        $input = input();
        if(empty($input['id'])){
            return message("记录ID不能为空", false);
        }
        if(empty($input['schoole_id'])){
            return message("请选择学校", false);
        }
        if(empty($input['grade_id'])){
            return message("请选择年级", false);
        }
        if(empty($input['class_id'])){
            return message("请选择班级", false);
        }
        $row = $this->model->find($input['id']);
        if(!empty($row['stu_id'])){
            $up = [
                'mark' => 1,
                'del_remark' => '',
                'schoole_id' => $input['schoole_id'],
                'grade_id' => $input['grade_id'],
                'class_id' => $input['class_id'],
            ];
            Db::table('think_student')->where('id',$row['stu_id'])->update($up);
        }else{
            return message("没有绑定学生保存失败", false);
        }
        return message("操作成功");
    }

    /**
     * 获取数据列表
     */
    public function getList()
    {
        $param = request()->param();

        // 查询条件
        $map = [];
        $sort = 'b.id desc';
        $is_sql = 0;

        if (!empty($param['imei'])) {
            $map[] = ['b.imei', 'like', '%' . $param['imei'] . '%'];
        }
        if (!empty($param['rfid'])) {
            $map[] = ['i.rfid', 'like', '%' . $param['rfid'] . '%'];
        }
        if (!empty($param['ip'])) {
            $map[] = ['conn.server_ip', 'like', '%' . $param['ip'] . '%'];
        }
        if (!empty($param['model_id'])) {
            $map[] = ['i.model_id', '=', $param['model_id']];
        }
        if (!empty($param['mac'])) {
            $map[] = ['i.mac', 'like', '%' . $param['mac'] . '%'];
        }
        if (!empty($param['ver'])) {
            $map[] = ['i.ver', 'like', '%' . $param['ver'] . '%'];
        }

        if (!empty($param['schoole_id'])) {
            $map[] = ['stu.schoole_id', '=', $param['schoole_id']];
        }
        if (!empty($param['name'])) {
            $map[] = ['stu.name', 'like', '%' . $param['name'] . '%'];
        }
        if (!empty($param['phone'])) {
            $map[] = ['stu.phone', 'like', '%' . $param['phone'] . '%'];
        }
        if (!empty($param['student_no'])) {
            $map[] = ['stu.student_no', 'like', '%' . $param['student_no'] . '%'];
        }

        //获取数据总数
        $count = $this->model->alias('b')
            ->leftJoin('device_imei i', 'b.imei = i.imei')
            ->leftJoin('student stu', 'b.imei = stu.imei')
            ->leftJoin('device_model model', 'i.model_id = model.id')
            ->leftJoin('user u', 'b.user_id = u.id')
            ->leftJoin('user bu', 'b.belong_user_id = bu.id')
            ->leftJoin('device_conn conn', 'conn.imei = i.imei')
            ->where($map)
            ->count();
        // 打印SQL
        if ($is_sql) {
            echo $this->model->getLastSql();
        }
        $list = [];
        if ($count > 0) {
            $field = [
                'b.*',
                'i.rfid',
                'conn.server_ip' => 'ip',
                'i.model_id',
                'i.mac',
                'i.ver',
                'i.is_active',
                'i.is_forbid',
                'i.active_time',
                'i.expire_time',
                'stu.name',
                'stu.phone',
                'stu.student_no',
                'stu.id_card',
                'stu.gender',
                'model.name' => 'model_name',
                'u.nickname' => 'user_name',
                'bu.nickname' => 'belong_user_name',
            ];

            $list = $this->model->alias('b')
                ->leftJoin('device_imei i', 'b.imei = i.imei')
                ->leftJoin('student stu', 'b.imei = stu.imei')
                ->leftJoin('device_model model', 'i.model_id = model.id')
                ->leftJoin('user u', 'b.user_id = u.id')
                ->leftJoin('user bu', 'b.belong_user_id = bu.id')
                ->leftJoin('device_conn conn', 'conn.imei = i.imei')
                ->where($map)
                ->order($sort)
                ->field($field)
                ->page(PAGE, PERPAGE)
                ->select()->each(function ($item){
                    $row = Db::table('think_device_location')->where('imei',$item['imei'])
                        ->where('create_time','>',strtotime(date('Y-m-d'))-48*3600)
                        ->find();
                    $item['is_active'] = $row?1:0;
                    $schoole_name = '';
                    $schoole_id = null;
                    $grade_id = null;
                    $grade_name = '';
                    $class_name = '';
                    $class_id = null;
                    if($item['stu_id']){
                        $stu = Db::table('think_student')->find($item['stu_id']);
                        if($stu){
                            $schoole = Db::table('think_schoole')->find($stu['schoole_id']);
                            $schoole_name = $schoole?$schoole['title']:'';
                            $schoole_id = $schoole?$schoole['id']:'';
                            if($schoole_id && $stu['grade_id']){
                                $gmap = [
                                    'schoole_id' => $schoole_id,
                                    'grade_key' => $stu['grade_id'],
                                ];
                                $g = Db::table('think_grade')->where($gmap)->where('mark',1)->find();
                                $grade_name = $g?$g['title']:'';
                                $grade_id = $g?$g['grade_key']:'';
                            }
                            if($schoole_id && $stu['grade_id'] && $stu['class_id']){
                                $cmap = [
                                    'schoole_id' => $schoole_id,
                                    'grade_id' => $stu['grade_id'],
                                    'class_key' => $stu['class_id'],
                                ];
                                $c = Db::table('think_class')->where($cmap)->where('mark',1)->find();
                                $class_name = $c?$c['title']:'';
                                $class_id = $c?$c['class_key']:'';
                            }
                        }

                    }
                    $item['schoole_name'] = $schoole_name;
                    $item['schoole_id'] = $schoole_id;
                    $item['grade_id'] = $grade_id;
                    $item['grade_name'] = $grade_name;
                    $item['class_id'] = $class_id;
                    $item['class_name'] = $class_name;
                });
        }

        //返回结果
        return array(
            "msg" => '操作成功',
            "code" => 0,
            "data" => $list,
            "count" => $count,
        );

    }


    public function delete()
    {
        // 参数
        $param = request()->param();
        // 记录ID
        $id = getter($param, "id");
        if (empty($id)) {
            return message("记录ID不能为空", false);
        }
        $row = DeviceBind::get($id);
        if (empty($row)) {
            return message("数据不存在", false);
        }
        Db::startTrans();
        try {
            DeviceBind::destroy($id);
            DeviceUnbind::create([
                'imei' => $row->imei,
                'stu_id' => $row->stu_id,
                'user_id' => $row->user_id,
            ]);
            delImeiBind($row->imei);
            $existed = $this->model->where('imei', $row->imei)->order("id asc")->find();
            if (!empty($existed)) {
                $existed['is_admin'] = 1;
                $existed->save();
            }

            Db::commit();

        } catch (\Throwable $e) {
            Db::rollback();
            trace('解绑异常：' . $e->getTraceAsString(), 'error');
            return message("解绑失败", false);
        }

        return message("解绑成功");
    }

    public function info()
    {
        $id = request()->param("id", 0);
        $info = [];
        if ($id) {
            $field = [
                'b.*',
                'i.rfid',
                'i.ip',
                'i.model_id',
                'i.mac',
                'i.ver',
                'i.is_active',
                'i.is_forbid',
                'i.active_time',
                'i.expire_time',
                'stu.name' => 'stu_name',
                'stu.student_no',
                'stu.phone' => 'stu_phone',
                'stu.id_card',
                'stu.gender',
                'model.name' => 'model_name',
            ];
            $info = $this->model->alias('b')
                ->leftJoin('device_imei i', 'b.imei = i.imei')
                ->leftJoin('student stu', 'b.stu_id = stu.id')
                ->leftJoin('device_model model', 'i.model_id = model.id')
                ->where('b.id', $id)
                ->field($field)
                ->find();
        }
        return message("操作成功", true, $info);
    }


    public function add($userId, $extra = [])
    {
        $param = request()->param();
        if (!empty($extra)) {
            $param = array_merge($param, $extra);
        }
        $imei = getter($param, "imei");
        if (empty($imei)) {
            return message("imei:设备IMEI不能为空", false);
        }
        $device_alias = getter($param, "device_alias");
        if (empty($device_alias)) {
            return message("device_alias:设备昵称不能为空", false);
        }
        $relation = getter($param, "relation");
        if (empty($relation)) {
            return message("relation:关系名称不能为空", false);
        }
        $default_show = getter($param, "default_show");
        if ($default_show != 1 && $default_show != 0) {
            return message("default_show:是否默认展示参数错误", false);
        }
        //unset($param['id']);
        // 获取用户信息
        if (empty($extra)) {
            $info = User::get(['id' => $userId]);
            if (!$info) {
                return message("用户信息不存在", false);
            }
            // 限制绑定设备个数
            $limit = 10;
            $count = $this->model->where('user_id', $userId)->count();
            if ($count >= $limit) {
                return message("最多只能绑定" . $limit . "个设备", false);
            }
        }

        $row = DeviceImei::get(['imei' => $imei]);
        if (empty($row)) {
            return message("imei不存在", false);
        }
        $student = Student::get(['imei' => $imei]);
        if (!empty($student)) {
            $param['stu_id'] = $student->id;
        }
        // 判断设备是否已经有管理员
        $bind_count = $this->model->where('imei', $imei)->where('user_id', 'neq', 0)->where('is_admin', 'eq', 1)->count();
        if ($bind_count == 0) {
            $param['is_admin'] = 1;
        }
        // 判断是否已经被自己绑定
        $binded_by_oneself = $this->model->get(['imei' => $imei, 'user_id' => $userId]);
        if ($binded_by_oneself) {
            return message("设备已经绑定，请勿重复绑定", false);
        }
        if ($default_show == 1) {
            $deviceBind = $this->model->get(['user_id' => $userId, 'default_show' => 1]);
            // 如果已经存在其他默认展示的，就将其他默认展示状态改为 0
            if ($deviceBind && $deviceBind->imei != $imei) {
                $deviceBind->default_show = 0;
                $deviceBind->save();
            }
        }
        $data = $this->model->get(['user_id' => 0, 'imei' => $imei]);
        // 如果已经存在学生先绑定设备生成的虚空家长则进行更新
        if ($data) {
            $param['id'] = $data->id;
            $param['update_time'] = time();
        }
        //unset($param['create_time'],$param['update_time'],$param['delete_time']);
        $param['user_id'] = $userId;
        /*$student = Student::get(['imei' => $imei, 'status' => 1]);
        if (empty($student)) {
            return message("imei未关联学生", false);
        }
        $param['stu_id'] = $student->id;*/
        //$this->model->allowField(true)->save($param,['imei' => $imei]);
        //$result = (new DeviceImei())->allowField(true)->save($param,['imei' => $imei]);
        $error = "";
        $result = $this->model->edit($param, $error);
        if (!$result) {
            return message($error, false);
        }
        return message("成功");
    }


    public function change($userId)
    {
        $param = request()->param();
        $imei = getter($param, "imei");
        $new_imei = getter($param, "new_imei");
        if (empty($imei)) {
            return message("原imei不能为空", false);
        }
        if (empty($new_imei)) {
            return message("新imei不能为空", false);
        }
        $info = User::get(['id' => $userId]);
        if (!$info) {
            return message("用户信息不存在", false);
        }
        $row = $this->model->where(['imei' => $imei])->find();
        if (empty($row)) {
            return message("原imei绑定信息不存在", false);
        }
        $check = DeviceImei::get(['imei' => $new_imei]);
        if (empty($check)) {
            return message("新imei不存在", false);
        }
        $is_admin = 0;
        $binded = $this->model->get(['imei' => $imei]);
        if (!$binded) {
            $param['is_admin'] = 1;
        }
        $result = $row->save([
            'imei' => $new_imei,
            'is_admin' => $is_admin,
        ]);
        $stu = Db::table('think_student')->where('imei',$imei)->where('mark',1)->find();
        if($stu){
            return message("已使用无法绑定", false);
        }
        //$new_imei
        Db::table('think_student')->where('imei',$imei)->update(['imei' => $new_imei]);
        Db::table('think_student_work_log')->where('imei',$imei)->update(['imei' => $new_imei]);
        Db::table('think_device_location')->where('imei',$imei)->update(['imei' => $new_imei]);
        Db::table('think_resort_log')->where('imei',$imei)->update(['imei' => $new_imei]);
        Db::table('think_heart_rate_log')->where('imei',$imei)->update(['imei' => $new_imei]);
        Db::table('think_device_step_records')->where('imei',$imei)->update(['imei' => $new_imei]);
        Db::table('think_terminal_relative')->where('imei',$imei)->update(['imei' => $new_imei]);
        Db::table('think_terminal_whitelist')->where('imei',$imei)->update(['imei' => $new_imei]);
        Db::table('think_temperature_log')->where('imei',$imei)->update(['imei' => $new_imei]);


        if (!$result) {
            return message("换绑失败", false);
        }
        return message("换绑成功");
    }

    public function del($userId)
    {
        $param = request()->param();
        $imei = getter($param, "imei");
        if (empty($imei)) {
            return message("imei不能为空", false);
        }
        // 获取用户信息
        $info = User::get(['id' => $userId]);
        if (!$info) {
            return message("用户信息不存在", false);
        }
        $row = DeviceImei::get(['imei' => $imei]);
        if (empty($row)) {
            return message("imei不存在", false);
        }
        $bindInfo = DeviceBind::get(['imei' => $imei, 'user_id' => $userId]);
        if (empty($bindInfo)) {
            return message($imei . "不是你绑定的设备，无法解绑", false);
        }
        try {
            $item = [
                'id' => $bindInfo['id'],
                'user_id' => 0,
                'default_show' => 0,
                'device_alias' => '未设置',
                'relation' => '未设置',
                'is_admin' => 0,
            ];
            $result = $this->model->edit($item);
            if (!$result) {
                return message('解绑失败', false);
            }
            // 查询是否有其他用户绑定此设备，有则将此用户设置为设备管理员，按绑定设备的先后顺位继承，排除 user_id 为 0 的用户
            $existed = $this->model->where('imei', $imei)->where('user_id', 'neq', 0)->order("id asc")->find();
            if (!empty($existed) && $bindInfo['is_admin'] == 1) {
                $existed['is_admin'] = 1;
                $existed->save();
            }
            return message("解绑成功");
        } catch (\Exception $e) {
            return message($e->getMessage(), false);
        }
    }

    public function updateDefaultShow($userId)
    {
        // 获取参数
        $param = request()->param();
        $imei = getter($param, "imei");
        if (empty($imei)) {
            return message("imei不能为空", false);
        }
        $default_show = getter($param, "default_show");
        if ($default_show != 1 && $default_show != 0) {
            return message("default_show:是否默认展示参数错误", false);
        }
        // 获取用户信息
        $info = User::get(['id' => $userId]);
        if (!$info) {
            return message("用户信息不存在", false);
        }
        $row = DeviceImei::get(['imei' => $imei]);
        if (empty($row)) {
            return message("imei不存在", false);
        }
        $bindInfo = DeviceBind::get(['imei' => $imei, 'user_id' => $userId]);
        if (empty($bindInfo)) {
            return message($imei . "不是你绑定的设备，无法切换默认展示状态", false);
        }
        if ($default_show == 1) {
            $deviceBind = $this->model->get(['user_id' => $userId, 'default_show' => 1]);
            // 如果已经存在其他默认展示的，就将其他默认展示状态改为 0
            if ($deviceBind && $deviceBind->imei != $imei) {
                $deviceBind->default_show = 0;
                $deviceBind->save();
            }
        }
        $item = [
            'id' => $bindInfo['id'],
            'default_show' => $default_show,
        ];
        $result = $this->model->edit($item);
        if (!$result) {
            return message("修改失败", false);
        }
        return message("修改成功");
    }

    public function setDevicePhone($userId)
    {
        // 获取参数
        $param = request()->param();
        $imei = getter($param, "imei");
        if (empty($imei)) {
            return message("imei不能为空", false);
        }
        $phone = getter($param, "phone");
        if (empty($phone)) {
            return message("phone不能为空", false);
        }
        // 获取用户信息
        $info = User::get(['id' => $userId]);
        if (!$info) {
            return message("用户信息不存在", false);
        }
        $row = DeviceImei::get(['imei' => $imei]);
        if (empty($row)) {
            return message("imei不存在", false);
        }
        $bindInfo = DeviceBind::get(['imei' => $imei, 'user_id' => $userId]);
        if (empty($bindInfo)) {
            return message($imei . "不是你绑定的设备，无法设置设备号码", false);
        }
        if ($bindInfo['is_admin'] == 0) {
            return message("你不是此设备的管理员，无法设置设备号码", false);
        }
        $result = db('device_imei')->where(['id' => $row['id']])->update(['phone' => $phone]);
        if (!$result) {
            return message("修改失败", false);
        }
        return message("修改成功");
    }

    public function getDevicePhone($userId)
    {
        $device_list = db('device_bind')->alias('t_bind')
            ->field('t_imei.imei,t_imei.phone')
            ->join('device_imei t_imei', 't_imei.imei = t_bind.imei')
            ->where('t_bind.user_id', $userId)
            ->select();
        if (empty($device_list)) {
            $device_list = [];
        }
        return message("操作成功", true, $device_list);
    }

    /**
     * 导出Excel
     * @throws \PHPExcel_Exception
     * @throws \PHPExcel_Reader_Exception
     * @throws \PHPExcel_Writer_Exception
     */
    public function exportExcel()
    {
        // 获取导出的数据源
        $res = $this->getList();
        $list = $res['data'];

        // 实例化PHPExcel类
        $objPHPExcel = new \PHPExcel();
        // 激活当前的sheet表
        $activeSheet = $objPHPExcel->setActiveSheetIndex(0);
        //5.设置表格头（即excel表格的第一行）
        $activeSheet->setCellValue('A1', '姓名')
            ->setCellValue('B1', 'IMEI')
            ->setCellValue('C1', '学号')
            ->setCellValue('D1', 'RFID')
            ->setCellValue('E1', '服务IP')
            ->setCellValue('F1', '身份证号')
            ->setCellValue('G1', '型号')
            ->setCellValue('H1', '蓝牙MAC')
            ->setCellValue('I1', '号码')
            ->setCellValue('J1', '关联用户')
            ->setCellValue('K1', '所属用户')
            ->setCellValue('L1', '激活时间')
            ->setCellValue('M1', '到期时间')
            ->setCellValue('N1', '性别')
            ->setCellValue('O1', '最近活跃')
            ->setCellValue('P1', '禁止')
            ->setCellValue('Q1', '版本号');
        //设置列水平居左
        $activeSheet->getStyle('A')->getAlignment()
            ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
        $activeSheet->getStyle('B')->getAlignment()
            ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
        $activeSheet->getStyle('C')->getAlignment()
            ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
        $activeSheet->getStyle('D')->getAlignment()
            ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
        $activeSheet->getStyle('E')->getAlignment()
            ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
        $activeSheet->getStyle('F')->getAlignment()
            ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
        $activeSheet->getStyle('I')->getAlignment()
            ->setHorizontal(\PHPExcel_Style_Alignment::HORIZONTAL_LEFT);

        // 设置单元格宽度
        $activeSheet->getColumnDimension('A')->setWidth(10);
        $activeSheet->getColumnDimension('B')->setWidth(20);
        $activeSheet->getColumnDimension('C')->setWidth(20);
        $activeSheet->getColumnDimension('D')->setWidth(20);
        $activeSheet->getColumnDimension('E')->setWidth(20);
        $activeSheet->getColumnDimension('F')->setWidth(20);
        $activeSheet->getColumnDimension('G')->setWidth(20);
        $activeSheet->getColumnDimension('H')->setWidth(20);
        $activeSheet->getColumnDimension('I')->setWidth(20);
        $activeSheet->getColumnDimension('L')->setWidth(20);
        $activeSheet->getColumnDimension('M')->setWidth(20);

        // 循环刚取出来的数组，将数据逐一添加到excel表格。
        for ($i = 0; $i < count($list); $i++) {
            $activeSheet->setCellValue('A' . ($i + 2), $list[$i]['name']);
            $activeSheet->setCellValue('B' . ($i + 2), $list[$i]['imei']);
            $activeSheet->setCellValue('C' . ($i + 2), $list[$i]['student_no']);
            $activeSheet->setCellValue('D' . ($i + 2), $list[$i]['rfid']);
            $activeSheet->setCellValue('E' . ($i + 2), $list[$i]['ip']);
            $activeSheet->setCellValue('F' . ($i + 2), $list[$i]['id_card']);
            $activeSheet->setCellValue('G' . ($i + 2), $list[$i]['model_name']);
            $activeSheet->setCellValue('H' . ($i + 2), $list[$i]['mac']);
            $activeSheet->setCellValue('I' . ($i + 2), $list[$i]['phone']);
            $user_id = $list[$i]['user_id'] ?? 0;
            $user_name = '';
            if ($user_id) {
                $user_name = User::where('id', $user_id)->value('realname');
            }
            $activeSheet->setCellValue('J' . ($i + 2), $user_name);

            $belong_user_id = $list[$i]['belong_user_id'] ?? 0;
            $belong_user_name = '';
            if ($belong_user_id) {
                $belong_user_name = User::where('id', $belong_user_id)->value('realname');
            }
            $activeSheet->setCellValue('K' . ($i + 2), $belong_user_name);
            $activeSheet->setCellValue('L' . ($i + 2), $list[$i]['active_time']);
            $activeSheet->setCellValue('M' . ($i + 2), $list[$i]['expire_time']);
            $gender = $list[$i]['gender'] == 1 ? '男' : '女';
            $activeSheet->setCellValue('N' . ($i + 2), $gender);
            $activeSheet->setCellValue('O' . ($i + 2), $list[$i]['is_active'] == 1 ? '是' : '否');
            $activeSheet->setCellValue('P' . ($i + 2), $list[$i]['is_forbid'] == 1 ? '是' : '否');
            $activeSheet->setCellValue('Q' . ($i + 2), $list[$i]['ver']);
        }
        // 设置保存的Excel表格名称
        $filename = '设备管理_' . date('YmdHis', time()) . ".xlsx";
        // 设置当前激活的sheet表格名称
        $activeSheet->setTitle('设备管理');
        // 保存本地文件
        $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
        $savePath = UPLOAD_TEMP_PATH . "/" . $filename;
        $objWriter->save($savePath);

        // 文件地址
        $filePath = get_image_url(str_replace(PUBLIC_PATH, "", $savePath));
        return message("操作成功", true, $filePath);
    }


}

